package org.flashbrighton.as3bots.components
{
	import flash.utils.Dictionary;
	
	import org.flashbrighton.as3bots.bots.BaseBot;
	import org.flashbrighton.as3bots.models.BotModel;
	
	public class ComponentManager
	{
		public static const MAX_NUM:int = 5;
		
		private var _componentsByBot:Dictionary;
		
		private var _engine:EngineComponent;
		private var _steering:SteeringComponent;
		private var _health:HealthComponent;
		private var _chassis:ChassisComponent;
		private var _armour:ArmourComponent;
		private var _turbo:TurboComponent;
		private var _botScanner:BotScannerComponent;
		
		
		public function ComponentManager()
		{
			init();
		}
		
		
		private function init():void
		{
			_componentsByBot = new Dictionary(true);
			
			_engine = new EngineComponent();
			_steering = new SteeringComponent();
			_health = new HealthComponent();
			_chassis = new ChassisComponent();
			_armour = new ArmourComponent();
			_turbo = new TurboComponent();
			_botScanner = new BotScannerComponent();
		}
		
		
		public function addToBot(name:String, bot:BaseBot):void
		{
			if (!ExtraComponents.validate(name)&&!CoreComponents.validate(name)) return;			
			
			if (_componentsByBot[bot] is Array && _componentsByBot[bot].length < MAX_NUM)
			{
				_componentsByBot[bot].push(name);
			}
			else
			{
				_componentsByBot[bot] = [name];
			}
		}
		
		
		/**
		 * Executes a bot's components from last to first.
		 */ 
		public function updateBot(botModel:BotModel):void 
		{			
			var components:Array = _componentsByBot[botModel.bot];
			var compName:String;
			for (var i:int = components.length - 1; i >= 0; i--) 
			{
				compName = components[i];
				getComponentByName(compName).update(botModel);
			}
		}
		
		
		public function getComponentByName(name:String):IComponent 
		{
			var comp:IComponent;
			
			switch (name) 
			{
				case CoreComponents.ENGINE:
				comp = _engine;
				break;
				
				case CoreComponents.STEERING:
				comp = _steering;
				break;
				
				case CoreComponents.HEALTH:
				comp = _health;
				break;
				
				case CoreComponents.CHASSIS:
				comp = _chassis;
				break;
				
				case ExtraComponents.ARMOUR:
				comp = _armour;
				break;				
				
				case ExtraComponents.TURBO:
				comp = _turbo;
				break;

				case ExtraComponents.BOTSCANNER:
				comp = _botScanner;
				break;
			}
			
			return comp;
		}
		
		
		public function hasComponent(name:String, bot:BaseBot):Boolean
		{
			return bot.components.indexOf(name) > -1;
		}
		
		
		public function get engine():EngineComponent
		{
			return _engine;
		}
		
		public function get steering():SteeringComponent
		{
			return _steering;
		}
		
		public function get health():HealthComponent
		{
			return _health;
		}
		
		public function get chassis():ChassisComponent
		{
			return _chassis;
		}
		
		public function get armour():ArmourComponent 
		{ 
			return _armour;
		}
		
		public function get turbo():TurboComponent 
		{ 
			return _turbo;
		}

	}
}